package com.sun.temp.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sun.temp.bean.Material;
import com.sun.temp.bean.Point;
import com.sun.temp.dto.TempDto;

import java.io.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class FileReadUtil {

    /**
     * 读取txt文件
     *
     * @param filepath
     * @return
     */
    private static Map<Double, Double> read(String filepath) {
        Material material = new Material();

        Map<Double, Double> map = new HashMap<>();

        File file = new File(filepath);
        BufferedReader reader = null;
        String tempString = null;

        String taSampleWeight = null;

        try {
            reader = new BufferedReader(new FileReader(file));
            while ((tempString = reader.readLine()) != null) {
                // 读取原始高度
                if (tempString.trim().contains("TaSampleWeight")) {
                    tempString = reader.readLine();
                    taSampleWeight = tempString.replaceAll("\\s+", "").split("=")[1];
                }
                // 取数从<Raw Data>行+2 开始
                if ("<Raw Data>".equals(tempString)) {
                    break;
                }
            }

            // 跳过两行，分别是title和unit
            reader.readLine();
            reader.readLine();

            while ((tempString = reader.readLine()) != null) {
                // 读到空行跳出
                if (StringUtils.isEmpty(tempString.trim())) {
                    break;
                }

                // No. Time Temp. TMA Load DTMA
                // 0 5 25.1477 0.012538 -10003.4 0.0998497
                // 取Temp和TMA
                Double temp = Double.parseDouble(tempString.split(" ")[2]);
                Double tma = Double.parseDouble(tempString.split(" ")[3]);
                map.put(temp, tma);
            }

            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        Set<Double> doubles = map.keySet();
        Double a = findClosestToForty(doubles, 40.0);
        Double b = findClosestToForty(doubles, 80.0);
        Double c = findClosestToForty(doubles, 190.0);
        Double d = findClosestToForty(doubles, 230.0);
        TempDto tempa = new TempDto();
        tempa.setTemp(a.toString());
        tempa.setTma(map.get(a).toString());
        material.setTempa(tempa);

        TempDto tempb = new TempDto();
        tempb.setTemp(b.toString());
        tempb.setTma(map.get(b).toString());
        material.setTempb(tempb);

        TempDto tempc = new TempDto();
        tempc.setTemp(c.toString());
        tempc.setTma(map.get(c).toString());
        material.setTempc(tempc);

        TempDto tempd = new TempDto();
        tempd.setTemp(d.toString());
        tempd.setTma(map.get(d).toString());
        material.setTempd(tempd);

        BigDecimal dTaSampleWeight = new BigDecimal(1);
        if (!StringUtils.isEmpty(taSampleWeight)) {
            dTaSampleWeight = BigDecimal.valueOf(Double.parseDouble(taSampleWeight));
        }

        // 计算斜率和交叉点
        BigDecimal xielv1 = calSlope(a, map.get(a), b, map.get(b));
        System.out.println("原始斜率1 = " + xielv1.toEngineeringString());
        xielv1 = xielv1.divide(dTaSampleWeight, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
        System.out.println("计算斜率1 = " + xielv1.toEngineeringString());

        BigDecimal xielv2 = calSlope(c, map.get(c), d, map.get(d));
        System.out.println("原始斜率2 = " + xielv2.toEngineeringString());
        xielv2 = xielv2.divide(dTaSampleWeight, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
        System.out.println("计算斜率2 = " + xielv2.toEngineeringString());

        Point jiaodian = findIntersectionPoint(a, map.get(a), b, map.get(b), c, map.get(c), d, map.get(d));
        System.out.println("交点 X 坐标 = " + jiaodian.getX());

        return map;
    }

    /**
     * 按目标值找最相近的数据
     *
     * @param numbers
     * @param target
     * @return
     */
    private static double findClosestToForty(Set<Double> numbers, double target) {
        double closest = 0.0;
        double minDistance = Double.POSITIVE_INFINITY;

        for (double number : numbers) {
            double distance = Math.abs(number - target);
            if (distance < minDistance) {
                minDistance = distance;
                closest = number;
            }
        }

        return closest;
    }

    /**
     * 计算斜率
     *
     * @return
     */
    private static BigDecimal calSlope(double x1, double y1, double x2, double y2) {
        return BigDecimal.valueOf((y2 - y1) / (x2 - x1));
    }

    /**
     * 获取两条线的交点
     *
     * @return
     */
    private static Point findIntersectionPoint(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
        double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

        if (d == 0) {
            return null; // 两条线段平行或共线，没有交点
        }

        double px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
        double py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;

        return new Point(px, py);
    }
}
